<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body id="body" something="非标准" data-about="Elephants">
    <input type="text" name="text" id="input" value="default" />

    <table border>
      <thead>
        <tr>
          <td></td>
          <td>特性（attribute）</td>
          <td>属性（property）</td>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>类型</td>
          <td>字符串</td>
          <td>任何值，标准的属性具有规范中描述的类型</td>
        </tr>
        <tr>
          <td>名称</td>
          <td>名称（name）大小写不敏感</td>
          <td>名称（name）大小写敏感</td>
        </tr>
      </tbody>
    </table>

    <script>
      // 在 html 中, 标签拥有属性（attributes），浏览器解析 html 时，根据标签创建 DOM 对象时，浏览器会辨别 ‘标准的’ 属性并创建 DOM 属性

      // id 是标准的，所以打印出 body
      console.log(document.body.id);
      // something 是非标准的，打印出 undefined
      console.log(document.body.something);

      // 每个元素的标准属性可能一样，页可能不一样，例如 body 标签就没有 input 标签的 type

      // 如果想访问非标准属性，可以使用下列方法（标准属性也可以使用）
      // 检查属性是否存在
      console.log(
        document.body.hasAttribute("id") ? "body 有 id" : "body 没有 id"
      );

      // 获取属性值
      console.log(document.body.getAttribute("id"));
      console.log(document.body.getAttribute("something"));

      // 修改属性值
      document.body.setAttribute("something", "修改");
      console.log(document.body.getAttribute("something"));

      // 删除属性
      document.body.removeAttribute("id");
      console.log(document.body.getAttribute("id"));

      // HTML attribute 和 DOM property 的区别
      // attribute 和 property 大多数情况下是一致的
      // 在 input 标签上，attribute 获取的 value字段初始值
      // 后续用户在输入框中修改的内容，通过 getAttribute 获取的值仍然是初始值
      // 最新值可以通过 input.value 获取
      console.log(
        document.getElementsByTagName("input")[0].getAttribute("value")
      );
      console.log(document.getElementsByTagName("input")[0].value);

      // 所有非标准的特性建议使用 date-* 定义，在 js 中通过 dataset 访问
      console.log(document.body.dataset.about);

      /*
      在大多数情况下，最好使用 DOM 属性。仅当 DOM 属性无法满足开发需求，并且我们真的需要特性时，才使用特性，例如：

      我们需要一个非标准的特性。但是如果它以 data- 开头，那么我们应该使用 dataset。
      我们想要读取 HTML 中“所写的”值。对应的 DOM 属性可能不同，例如 href 属性一直是一个 完整的 URL，但是我们想要的是“原始的”值。
      */
    </script>
  </body>
</html>
